home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 6 / The Arsenal Files 6 (Arsenal Computer).ISO / prg_casm / jlvesa11.zip / JLVESA22.ASM < prev    next >
Assembly Source File  |  1995-11-14  |  8KB  |  366 lines

  1. ; This routine is part of VESA SVGA -library
  2. ;
  3. ; Copyright 1994 Johannes Lehtinen
  4. ; All rights reserved
  5.  
  6. model large,c
  7. p386
  8.  
  9. include "jlvesads.asm"
  10.  
  11. extrn vesa_repos_w:far
  12.  
  13. segment jlvesa22_TEXT USE16 'CODE'
  14. assume cs:jlvesa22_TEXT
  15.  
  16. ; void JVImage_DrawOnLimited(JLSWord x, JLSWord y, JLUWord width,
  17. ;                            JLUWord height, void *image, JLSWord lx,
  18. ;                            JLSWord ly, JLUWord lwidth, JLUWord lheight)
  19. ;
  20. ; Puts image to screen, color 0 is transparent. Output only in limited area.
  21.  
  22. ; Some information
  23.  
  24. bl_linesleft   dw ?  ; Lines left to draw
  25. bl_repolines   dw ?  ; Lines before next reposition
  26. bl_overflines  dw ?  ; Lines before next overflow
  27. bl_left        dw ?  ; Pixels outside the left border
  28. bl_up          dw ?  ; Pixels outside the upper border
  29. bl_right       dw ?  ; Pixels outside the right border
  30. bl_width       dw ?  ; Pixels on screen horizontally
  31.  
  32. proc JVImage_DrawOnLimited far
  33.    public JVImage_DrawOnLimited
  34.  
  35.    push  bp
  36.    mov   bp,sp
  37.    push  si
  38.    push  di
  39.    push  ds
  40.    push  es
  41.    push  fs
  42.  
  43.    mov   ax,JLVesa_Data
  44.    mov   fs,ax
  45.  
  46.    mov   [cs:bl_left],0
  47.    mov   [cs:bl_up],0
  48.    mov   [cs:bl_right],0
  49.  
  50.    ; Make sure the block is on limited area
  51.    ; Check that x>=lx
  52.  
  53.    mov   ax,[ss:bp+18]
  54.    cmp   [ss:bp+6],ax
  55.    jge   short x_not_below
  56.  
  57.    ; X is less than lx
  58.  
  59.    sub   ax,[ss:bp+6]
  60.    mov   [cs:bl_left],ax
  61.  
  62.    ; Check that y>=ly
  63.  
  64. x_not_below:
  65.    mov   ax,[ss:bp+20]
  66.    cmp   [word ptr ss:bp+8],ax
  67.    jge   short y_not_below
  68.  
  69.    ; Y is less than 0
  70.  
  71.    sub   ax,[ss:bp+8]
  72.    mov   [cs:bl_up],ax
  73.  
  74.    ; Calculate pixels on limited area at this point
  75.  
  76. y_not_below:
  77.    mov   ax,[ss:bp+10]
  78.    sub   ax,[cs:bl_left]
  79.    mov   [cs:bl_width],ax
  80.    mov   ax,[ss:bp+12]
  81.    sub   ax,[cs:bl_up]
  82.    mov   [cs:bl_linesleft],ax
  83.  
  84.    mov   ax,[ss:bp+6]
  85.    add   ax,[ss:bp+10]
  86.    sub   ax,[ss:bp+18]
  87.    cmp   [ss:bp+22],ax
  88.    jg    short width_not_above
  89.  
  90.    ; Wider than limited area
  91.  
  92.    sub   ax,[ss:bp+22]
  93.    mov   [cs:bl_right],ax
  94.    mov   ax,[ss:bp+10]
  95.    sub   ax,[cs:bl_left]
  96.    sub   ax,[cs:bl_right]
  97.    mov   [cs:bl_width],ax
  98.  
  99. width_not_above:
  100.    mov   ax,[ss:bp+8]
  101.    add   ax,[ss:bp+12]
  102.    sub   ax,[ss:bp+20]
  103.    cmp   [ss:bp+24],ax
  104.    jg    short height_not_above
  105.  
  106.    ; Heigher than limited area
  107.  
  108.    sub   ax,[ss:bp+24]
  109.    mov   bx,ax
  110.    mov   ax,[ss:bp+12]
  111.    sub   ax,[cs:bl_up]
  112.    sub   ax,bx
  113.    mov   [cs:bl_linesleft],ax
  114.  
  115.    ; Check that width or height is not negative
  116.  
  117. height_not_above:
  118.    cmp   [cs:bl_width],0
  119.    jle   end_of_block
  120.    cmp   [cs:bl_linesleft],0
  121.    jle   end_of_block
  122.  
  123.    ; Calculate absolute address of starting point
  124.  
  125.    xor   eax,eax              ; Calculate address of start of line
  126.    xor   ebx,ebx
  127.    mov   ax,[ss:bp+8]
  128.    add   ax,[cs:bl_up]
  129.    mov   bx,[fs:LWidth]
  130.    mul   ebx
  131.    mov   bx,[ss:bp+6]         ; Calculate address of starting point
  132.    add   bx,[cs:bl_left]
  133.    add   eax,ebx
  134.    add   eax,[fs:AStart]      ; Calculate address if scrolled
  135.    mov   edx,eax
  136.  
  137.    ; Initialize registers used
  138.  
  139.    mov   ax,[fs:WWSeg]
  140.    mov   es,ax
  141.    cld                        ; Direction forward
  142.  
  143.    ; Reposition window if necessary
  144.  
  145.    cmp   [fs:WAStart],edx
  146.    jbe   short not_bef_win
  147.    call  far vesa_repos_w
  148.    jmp   short go_drawing
  149.  
  150. not_bef_win:
  151.    mov   eax,[fs:WAStart]
  152.    add   eax,[fs:WSize]
  153.    cmp   edx,eax
  154.    jb    short go_drawing
  155.    call  far vesa_repos_w
  156.  
  157.    ; Calculate current offset
  158.  
  159. go_drawing:
  160.    mov   edi,edx
  161.    sub   edi,[fs:WAStart]
  162.  
  163.    ; Read DS:SI
  164.  
  165.    xor   eax,eax
  166.    mov   ax,[cs:bl_up]
  167.    xor   ebx,ebx
  168.    mov   bx,[ss:bp+10]        ; EBX is width of image
  169.    push  edx
  170.    mul   ebx
  171.    pop   edx
  172.    mov   bx,[cs:bl_left]
  173.    add   eax,ebx              ; EAX is number of bytes to add to SI
  174.  
  175.    xor   esi,esi
  176.    mov   si,[ss:bp+14]        ; Read SI and make addition
  177.    add   esi,eax
  178.  
  179.    mov   ebx,esi
  180.    shr   ebx,4
  181.    and   si,0fH
  182.    mov   ax,[ss:bp+16]        ; Read DS and make addition
  183.    add   ax,bx
  184.    mov   ds,ax
  185.  
  186.    ; Drawing loop
  187.  
  188.    ; First calculate, how many lines can be drawn without address overflow.
  189.    ; Check both ES:DI and DS:SI.
  190.  
  191.    ; First check how many lines before window reposition
  192.  
  193. draw_loop:
  194.    cmp   [cs:bl_linesleft],0
  195.    je    end_of_block
  196.  
  197.    mov   eax,[fs:WAStart]
  198.    add   eax,[fs:WSize]
  199.    dec   eax
  200.    sub   eax,edx
  201.    xor   ebx,ebx
  202.    mov   bx,[fs:LWidth]
  203.    push  edx
  204.    xor   edx,edx
  205.    div   ebx
  206.    pop   edx
  207.  
  208.    cmp   [cs:bl_linesleft],ax ; Check if fewer lines left than possible to draw on the page
  209.    jae   short jump_0
  210.    mov   ax,[cs:bl_linesleft]
  211.  
  212. jump_0:
  213.    mov   [cs:bl_repolines],ax
  214.  
  215.    ; Then check how many lines before DS:SI overflow
  216.  
  217.    mov   eax,10000H
  218.    sub   eax,esi
  219.    push  edx
  220.    xor   edx,edx
  221.    xor   ebx,ebx
  222.    mov   bx,[fs:LWidth]
  223.    div   ebx
  224.    pop   edx
  225.  
  226.    cmp   [cs:bl_linesleft],ax ; Check if fewer lines left than possible to draw before overflow
  227.    jae   short jump_1
  228.    mov   ax,[cs:bl_linesleft]
  229.  
  230. jump_1:
  231.    mov   [cs:bl_overflines],ax
  232.  
  233.    ; Start drawing as many lines as possible before
  234.    ; First check if normal lines can be drawn next at all
  235.  
  236. draw_line:
  237.    cmp   [cs:bl_overflines],0
  238.    je    overf_check
  239.  
  240.    cmp   [cs:bl_repolines],0
  241.    je    short special_line
  242.  
  243.    mov   cx,[cs:bl_width]     ; Width of the block
  244.    call  near movsbtr
  245.  
  246.    add   di,[fs:LWidth]       ; Move to the start of next line
  247.    sub   di,[cs:bl_width]
  248.  
  249.    xor   ecx,ecx
  250.    mov   cx,[fs:LWidth]
  251.    add   edx,ecx
  252.    add   si,[cs:bl_right]
  253.    add   si,[cs:bl_left]
  254.  
  255.    dec   [cs:bl_repolines]
  256.    dec   [cs:bl_overflines]
  257.    dec   [cs:bl_linesleft]
  258.    jmp   short draw_line
  259.  
  260.    ; Draw line, which is between two pages
  261.  
  262. special_line:
  263.    mov   ecx,[fs:WAStart]     ; Calculate how line is divided
  264.    add   ecx,[fs:WSize]
  265.    sub   ecx,edx
  266.    cmp   [cs:bl_width],cx
  267.    jbe   short line_on_current   ; Line on current page
  268.  
  269.    ; Line is divided on both pages
  270.  
  271.    mov   bx,[cs:bl_width]     ; BX = length of the line on next page
  272.    sub   bx,cx
  273.    call  near movsbtr         ; Draw line on current page
  274.  
  275.    xor   ecx,ecx
  276.    mov   cx,[fs:LWidth]
  277.    add   edx,ecx              ; Switch on next page
  278.    call  far vesa_repos_w
  279.    mov   edi,edx              ; Calculate new DI
  280.    xor   ecx,ecx
  281.    mov   cx,[fs:LWidth]
  282.    sub   edi,ecx
  283.    xor   ecx,ecx
  284.    mov   cx,[cs:bl_width]
  285.    add   edi,ecx
  286.    sub   edi,[fs:WAStart]
  287.    sub   di,bx
  288.  
  289.    mov   cx,bx                ; Draw line on next page
  290.    call  near movsbtr
  291.  
  292.    add   di,[fs:LWidth]       ; Move on the next line
  293.    sub   di,[cs:bl_width]
  294.  
  295.    add   si,[cs:bl_right]
  296.    add   si,[cs:bl_left]
  297.  
  298.    dec   [cs:bl_linesleft]
  299.    jnz   draw_loop
  300.    jmp   short end_of_block
  301.  
  302.    ; Line is on current page
  303.  
  304. line_on_current:
  305.    mov   cx,[cs:bl_width]     ; Draw line on this page
  306.    call  near movsbtr
  307.  
  308.    xor   ecx,ecx
  309.    mov   cx,[fs:LWidth]
  310.    add   edx,ecx
  311.    call  far vesa_repos_w
  312.    mov   edi,edx              ; Move to start of next line
  313.    sub   edi,[fs:WAStart]
  314.  
  315.    add   si,[cs:bl_right]
  316.    add   si,[cs:bl_left]
  317.  
  318.    dec   [cs:bl_linesleft]
  319.    jnz   draw_loop
  320.    jmp   short end_of_block
  321.  
  322.    ; Handle DS:SI overflow
  323.  
  324. overf_check:
  325.    mov   ax,si
  326.    shr   ax,4
  327.    mov   bx,ds
  328.    add   ax,bx
  329.    mov   ds,ax
  330.    and   si,0fH
  331.    jmp   draw_loop
  332.  
  333.    ; End drawing
  334.  
  335. end_of_block:
  336.    pop   fs
  337.    pop   es
  338.    pop   ds
  339.    pop   di
  340.    pop   si
  341.    pop   bp
  342.    retf
  343.  
  344. endp JVImage_DrawOnLimited
  345.  
  346. ; This procedure MOVSBs CX bytes (color 0 transparent)
  347.  
  348. movsbtr_0:
  349.    inc   di
  350.    inc   si
  351.    dec   cx
  352.    jz    short movsbtr_end
  353. movsbtr:
  354.    cmp   [byte ptr ds:si],0
  355.    je    short movsbtr_0
  356.    movsb
  357.    dec   cx
  358.    jnz   short movsbtr
  359. movsbtr_end:
  360.    retn
  361.  
  362. ends
  363.  
  364. end
  365.  
  366.